import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowData;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;

/**
 * This is a dialog class which support managing some basic data , for instance,
 * roles,skill types,task types and so on.
 * 
 * @author zhongnanhai
 *
 */
public class BasicDataDialog extends Dialog{
	/**The main tabs container which hold roles tab,task types tab,skill types tab.*/
	private CTabFolder tabContainer = null;
	//role table and skill table
	private Table roleTable = null, skillTable = null;
	private Text timesTxt = null;
	/**
	 * The constructor with a default style.
	 * @param parent its parent window
	 */
	public BasicDataDialog(Shell parent){
		this(parent,SWT.DIALOG_TRIM | SWT.CLOSE | SWT.PRIMARY_MODAL);
	}
	/**
	 * The constructor of BasicDataDialog
	 * 
	 * @param parent its parent window
	 * @param style its specific style
	 */
	public BasicDataDialog(Shell parent, int style) {
		super(parent, style);
		// TODO Auto-generated constructor stub
	}
	/**
	 * The open function of a dialog class.
	 */
	public void open(){
		Shell shell = new Shell(getParent(),getStyle());
		shell.setText("Basic data");
		createContents(shell);
		Display display = getParent().getDisplay();
		shell.setSize(275, 240);
		int x = getParent().getBounds().x + (getParent().getBounds().width - shell.getBounds().width)/2;
		int y = getParent().getBounds().y + (getParent().getBounds().height - shell.getBounds().height)/2;
		shell.setLocation(x,y);
		shell.open();
		while(!shell.isDisposed()){
			if(!display.readAndDispatch())
				display.sleep();
		}
	}
	/**
	 * Create all of the contents/controls of this dialog.
	 * @param shell the dialog window
	 */
	private void createContents(final Shell shell){
		shell.setLayout(new FillLayout());
		tabContainer = new CTabFolder(shell,SWT.TOP|SWT.FLAT);
		createRolesTab(shell);
		createSkillTypesTab(shell);
		createSimulationTab(shell);
		//when closing the window,save the roles and skills
		shell.addDisposeListener(new DisposeListener(){
			@Override
			public void widgetDisposed(DisposeEvent e) {
				// TODO Auto-generated method stub
				//save the roles
				int n = roleTable.getItemCount();
				String[] roles = new String[n];
				String[] descriptions = new String[n];
				int i = 0;
				for(TableItem item:roleTable.getItems()){
					roles[i] = item.getText(1);
					descriptions[i] = item.getText(2);
					i ++;
				}
				AllBasicData.roles = roles;
				AllBasicData.dscriptionOfRole = descriptions;
				//save the skills
				n = skillTable.getItemCount();
				String[] skills = new String[n];
				descriptions = new String[n];
				i = 0;
				for(TableItem item:skillTable.getItems()){
					skills[i] = item.getText(1);
					descriptions[i] = item.getText(2);
					i ++;
				}
				AllBasicData.skills = skills;
				AllBasicData.dscriptionOfSkill = descriptions;
				
				try{
					int times = Integer.parseInt(timesTxt.getText());
					AllBasicData.simulationTimes = times;
				}catch(Exception exp){
					Utilities.showMessage(shell, SWT.ICON_ERROR|SWT.OK, "The simulation times" +
							"is not correct!");
				}
			}
			
		});
	}
	/**
	 * Create the roles tab of the shell window
	 * @param shell its parent window
	 */
	private void createRolesTab(final Shell shell){
		CTabItem rolesTabItem = new CTabItem(tabContainer,SWT.NONE);
		rolesTabItem.setText("Roles");
		Composite composite = new Composite(tabContainer,SWT.NONE);
		rolesTabItem.setControl(composite);
		composite.setLayout(new GridLayout(3,true));
		roleTable = new Table(composite,SWT.BORDER);
		roleTable.setHeaderVisible(true);roleTable.setLinesVisible(true);
		roleTable.setLinesVisible(true);
		final TableColumn[] columns = new TableColumn[3];
		columns[0] = new TableColumn(roleTable,SWT.NONE);
		columns[0].setText("ID");
		columns[1] = new TableColumn(roleTable,SWT.NONE);
		columns[1].setText("Role");
		columns[2] = new TableColumn(roleTable,SWT.NONE);
		columns[2].setText("Description");
		for(int i=0;i<3;i++) columns[i].pack();
		
		GridData data = new GridData();
		data.horizontalAlignment = GridData.FILL;
		data.grabExcessHorizontalSpace = true;
		data.horizontalSpan = 3;
		data.heightHint = 60;
		roleTable.setLayoutData(data);
		Label nameLbl = new Label(composite,SWT.LEFT);
		nameLbl.setText("Role Name:");
		data = new GridData();
		data.horizontalSpan = 1;
		data.horizontalAlignment = GridData.FILL;
		nameLbl.setLayoutData(data);
		final Text nameTxt = new Text(composite,SWT.BORDER);
		nameTxt.setTextLimit(24);
		data = new GridData();
		data.horizontalSpan = 2;
		data.horizontalAlignment = GridData.FILL;
		nameTxt.setLayoutData(data);
		Label dscribLbl = new Label(composite,SWT.LEFT);
		dscribLbl.setText("Description:");
		data = new GridData();
		data.horizontalSpan = 1;
		data.horizontalAlignment = GridData.FILL;
		dscribLbl.setLayoutData(data);
		final Text dscribTxt = new Text(composite,SWT.BORDER|SWT.MULTI|SWT.WRAP|SWT.V_SCROLL);
		data = new GridData(GridData.FILL_BOTH);
		data.verticalSpan = 3;
		data.horizontalSpan = 2;
		data.horizontalAlignment = GridData.FILL;
		dscribTxt.setLayoutData(data);
		new Label(composite,SWT.NONE);
		new Label(composite,SWT.NONE);
		Button okBtn = new Button(composite,SWT.PUSH);
		okBtn.setText("Insert");
		okBtn.setLayoutData(new GridData(GridData.FILL_BOTH));
		new Label(composite,SWT.NONE);
		Button cancelBtn = new Button(composite,SWT.PUSH);
		cancelBtn.setText("Cancel");
		cancelBtn.setLayoutData(new GridData(GridData.FILL_BOTH));
		
		int i = 0;
		for(i=0;i<AllBasicData.roles.length;i++){
			TableItem item = new TableItem(roleTable,SWT.NONE);
			item.setText(0, (i + 1) + "");
			item.setText(1, AllBasicData.roles[i]);
			item.setText(2, AllBasicData.dscriptionOfRole[i]);
		}
				
		//add necessary action to corresponding controls
		okBtn.addSelectionListener(new SelectionAdapter(){
			public void widgetSelected(SelectionEvent e){
				if(nameTxt.getText().trim().isEmpty())
					dscribTxt.setText("");
				else{
					roleTable.setRedraw(false);
					String name = nameTxt.getText().trim();
					String description = dscribTxt.getText().trim();
					String id = (roleTable.getItemCount()+1)+"";
					TableItem item = new TableItem(roleTable,SWT.NONE);
					item.setText(0, id);
					item.setText(1, name);
					item.setText(2, description);
					nameTxt.setText("");
					dscribTxt.setText("");
					for(int i=0;i<3;i++) columns[i].pack();
					roleTable.setRedraw(true);
				}
			}
		});
		cancelBtn.addSelectionListener(new SelectionAdapter(){
			public void widgetSelected(SelectionEvent e){
				shell.dispose();
			}
		});
	}
	/**
	 * Create the skill types tab of the shell window
	 * @param shell its parent window
	 */
	private void createSkillTypesTab(final Shell shell){
		CTabItem skillTypesTabItem = new CTabItem(tabContainer,SWT.NONE);
		skillTypesTabItem.setText("Skill Types");
		Composite composite = new Composite(tabContainer,SWT.NONE);
		skillTypesTabItem.setControl(composite);
		composite.setLayout(new GridLayout(3,true));
		skillTable = new Table(composite,SWT.BORDER);
		skillTable.setHeaderVisible(true);skillTable.setLinesVisible(true);
		skillTable.setLinesVisible(true);
		final TableColumn[] columns = new TableColumn[3];
		columns[0] = new TableColumn(skillTable,SWT.NONE);
		columns[0].setText("ID");
		columns[1] = new TableColumn(skillTable,SWT.NONE);
		columns[1].setText("Skill");
		columns[2] = new TableColumn(skillTable,SWT.NONE);
		columns[2].setText("Description");
		for(int i=0;i<3;i++) columns[i].pack();
		GridData data = new GridData();
		data.horizontalAlignment = GridData.FILL;
		data.grabExcessHorizontalSpace = true;
		data.horizontalSpan = 3;
		data.heightHint = 60;
		skillTable.setLayoutData(data);
		Label nameLbl = new Label(composite,SWT.LEFT);
		nameLbl.setText("Skill Type Name:");
		data = new GridData();
		data.horizontalSpan = 1;
		data.horizontalAlignment = GridData.FILL;
		nameLbl.setLayoutData(data);
		final Text nameTxt = new Text(composite,SWT.BORDER);
		nameTxt.setTextLimit(24);
		data = new GridData();
		data.horizontalSpan = 2;
		data.horizontalAlignment = GridData.FILL;
		nameTxt.setLayoutData(data);
		Label dscribLbl = new Label(composite,SWT.LEFT);
		dscribLbl.setText("Description:");
		data = new GridData();
		data.horizontalSpan = 1;
		data.horizontalAlignment = GridData.FILL;
		dscribLbl.setLayoutData(data);
		final Text dscribTxt = new Text(composite,SWT.BORDER|SWT.MULTI|SWT.WRAP|SWT.V_SCROLL);
		data = new GridData(GridData.FILL_BOTH);
		data.verticalSpan = 3;
		data.horizontalSpan = 2;
		data.horizontalAlignment = GridData.FILL;
		dscribTxt.setLayoutData(data);
		new Label(composite,SWT.NONE);
		new Label(composite,SWT.NONE);
		Button okBtn = new Button(composite,SWT.PUSH);
		okBtn.setText("Insert");
		okBtn.setLayoutData(new GridData(GridData.FILL_BOTH));
		new Label(composite,SWT.NONE);
		Button cancelBtn = new Button(composite,SWT.PUSH);
		cancelBtn.setText("Cancel");
		cancelBtn.setLayoutData(new GridData(GridData.FILL_BOTH));
		
		int i = 0;
		for(i=0;i<AllBasicData.skills.length;i++){
			TableItem item = new TableItem(skillTable,SWT.NONE);
			item.setText(0, (i + 1) + "");
			item.setText(1, AllBasicData.skills[i]);
			item.setText(2, AllBasicData.dscriptionOfSkill[i]);
		}
		//add necessary action to corresponding controls
		okBtn.addSelectionListener(new SelectionAdapter(){
			public void widgetSelected(SelectionEvent e){
				if(nameTxt.getText().trim().isEmpty())
					dscribTxt.setText("");
				else{
					skillTable.setRedraw(false);
					String name = nameTxt.getText().trim();
					String description = dscribTxt.getText().trim();
					String id = (skillTable.getItemCount()+1)+"";
					TableItem item = new TableItem(skillTable,SWT.NONE);
					item.setText(0, id);
					item.setText(1, name);
					item.setText(2, description);
					nameTxt.setText("");
					dscribTxt.setText("");
					for(int i=0;i<3;i++) columns[i].pack();
					skillTable.setRedraw(true);
				}
			}
		});
		cancelBtn.addSelectionListener(new SelectionAdapter(){
			public void widgetSelected(SelectionEvent e){
				shell.dispose();
			}
		});
	}
	/**
	 * Create the simulation tab 
	 * @param shell its parent window
	 */
	private void createSimulationTab(final Shell shell){
		CTabItem simulationTabItem = new CTabItem(tabContainer,SWT.NONE);
		simulationTabItem.setText("Simulation Parameters");
		Composite composite = new Composite(tabContainer,SWT.NONE);
		simulationTabItem.setControl(composite);
		
		RowLayout layout = new RowLayout(SWT.HORIZONTAL);
		composite.setLayout(layout);
		
		RowData data = new RowData();
		data.width = 100;
		Label timesLbl = new Label(composite,SWT.NONE);
		timesLbl.setText("Simulation Times:");
		timesLbl.setLayoutData(data);
		
		data = new RowData();
		data.width = 50;
		timesTxt = new Text(composite,SWT.BORDER);
		timesTxt.setText(AllBasicData.simulationTimes+"");
		timesTxt.setLayoutData(data);
	}
	public static void main(String[] args) throws Exception{
		Display display = new Display();
		Shell shell = new Shell(display);
		new BasicDataDialog(shell,SWT.DIALOG_TRIM).open();
		while(!shell.isDisposed()){
			if(!display.readAndDispatch())
				display.sleep();
		}
		display.dispose();
	}

}
